package com.xindacloud.sms.adapter.service.sms.impl;

import com.google.gson.Gson;
import com.nexmo.client.NexmoClientException;
import com.nexmo.client.sms.SmsSubmissionResponse;
import com.nexmo.client.sms.messages.TextMessage;
import com.xindacloud.sms.adapter.bo.SubmitMessageBO;
import com.xindacloud.sms.adapter.entity.SmsSubmissionRecord;
import com.xindacloud.sms.adapter.entity.SmsUserAllowOperator;
import com.xindacloud.sms.adapter.exception.ServiceException;
import com.xindacloud.sms.adapter.service.business.ISmsSubmissionRecordService;
import com.xindacloud.sms.adapter.service.business.ISmsUserAllowOperatorService;
import com.xindacloud.sms.adapter.service.business.ISmsUserService;
import com.xindacloud.sms.adapter.service.factory.NexmoClientFactory;
import com.xindacloud.sms.adapter.service.sms.ISubmitMessageService;
import com.xindacloud.sms.adapter.utils.MessageTypeHelp;
import com.xindacloud.sms.adapter.utils.StatusEum;
import com.xindacloud.sms.adapter.utils.UnionResultHelp;
import com.xindacloud.sms.adapter.vo.SubmitMessageResultVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Objects;

@Service("nexmoSubmitMessageService")
@Slf4j
public class NexmoSubmitMessageServiceImpl implements ISubmitMessageService<SubmitMessageBO, SubmitMessageResultVO> {

    @Autowired
    private ISmsUserAllowOperatorService smsUserAllowOperatorService;
    @Autowired
    private ISmsSubmissionRecordService smsSubmissionRecordService;
    @Autowired
    private ISmsUserService smsUserService;

    private final NexmoClientFactory nexmoClientFactory;

    @Autowired
    public NexmoSubmitMessageServiceImpl(NexmoClientFactory nexmoClientFactory) {
        this.nexmoClientFactory = nexmoClientFactory;
    }

    @Override
    public SubmitMessageResultVO submitMessage(SubmitMessageBO submitMessageBO) {

        final String recipient = submitMessageBO.getRecipient();
        final String senderId = submitMessageBO.getSenderId();
        final String messageBody = submitMessageBO.getMessageBody();
        final Integer userId = submitMessageBO.getUserId();
        final String taskId = submitMessageBO.getTaskId();
        final String countryCode = submitMessageBO.getCountryCode();
        final String countryPrefix = submitMessageBO.getCountryPrefix();
        final String agentId = submitMessageBO.getAgentId();
        final BigDecimal costPrice = submitMessageBO.getCostPrice();
        try {
            TextMessage message = new TextMessage(senderId, recipient, messageBody, MessageTypeHelp.isUnicode(messageBody));
            message.setStatusReportRequired(true);
            message.setCallbackUrl(submitMessageBO.getCallBackUrl());
            SmsSubmissionResponse response = nexmoClientFactory.getNexmoClient(submitMessageBO.getApiKey(),
                    submitMessageBO.getApiSecret(), submitMessageBO.getApiUrl()).getSmsClient().submitMessage(message);
            log.info("Nexmo发送返回结果:{}", new Gson().toJson(response));
            SubmitMessageResultVO resultVO = new SubmitMessageResultVO();
            resultVO.setMessageCount(response.getMessageCount());
            response.getMessages()
                    .forEach(mp -> {
                        resultVO.setErrorText(mp.getErrorText());
                        resultVO.setMessageId(mp.getId());
                        resultVO.setNetwork(mp.getNetwork());
                        resultVO.setSubmitStatus(mp.getStatus().getMessageStatus());
                    });
            //根据返回的network查询当前号码所属国家的售价
            final String network = resultVO.getNetwork();
            SmsUserAllowOperator allowOperator = smsUserAllowOperatorService
                    .queryOneMaxPriceOrderByDesc(userId, countryCode, countryPrefix, network);
            if (Objects.isNull(allowOperator)) {
                throw new ServiceException("未同步运营商价格,或未找到:" + network + "服务通道.", UnionResultHelp.StatusEnum.Fail.code());
            }
            final BigDecimal price = allowOperator.getPrice();
            final Integer messageCount = resultVO.getMessageCount();
            final BigDecimal calcMessagePrice = MessageTypeHelp.calcMessagePrice(price, messageCount);
            final String messageId = resultVO.getMessageId();
            final boolean messageIdNotEmpty = StringUtils.isNotEmpty(messageId);
            final SmsSubmissionRecord submissionRecord = SmsSubmissionRecord.builder()
                    .agentId(messageIdNotEmpty ? agentId : "")
                    .free(messageIdNotEmpty ? calcMessagePrice : BigDecimal.ZERO)
                    .costPrice(messageIdNotEmpty ? costPrice : BigDecimal.ZERO)
                    .countryCode(countryCode)
                    .prefix(countryPrefix)
                    .messageId(messageId)
                    .messageCount(messageCount)
                    .network(network)
                    .submitStatusCode(resultVO.getSubmitStatus())
                    .finalStatus(messageIdNotEmpty ? StatusEum.SUBMITTED.desc : StatusEum.FAILED.desc)
                    .sendTo(recipient)
                    .taskId(taskId)
                    .userId(userId)
                    .errorText(resultVO.getErrorText())
                    .minus(true)
                    .build();
            smsSubmissionRecordService.updateSmsSubmissionRecordFor(submissionRecord);
            if (messageIdNotEmpty) {
                //更新用户账户
                smsUserService.updateSmsPrice(userId, calcMessagePrice);
            }
            return resultVO;
        } catch (NexmoClientException e) {
            log.error("#### 发送短信异常:{}", e.getMessage(), e);
            throw new ServiceException("短信发送异常".concat(e.getMessage()), UnionResultHelp.StatusEnum.BadRequest.code());
        }
    }

}
